package cn.unknowpupil.controller.system;

import cn.unknowpupil.common.core.configure.RsaProperties;
import cn.unknowpupil.common.core.enums.LoginEnum;
import cn.unknowpupil.common.core.utils.RsaUtils;
import cn.unknowpupil.authentication.oauth.UsernamePasswordLoginAuthentication;
import cn.unknowpupil.common.core.resopnse.ResultResponse;
import cn.unknowpupil.common.security.component.TokenService;
import cn.unknowpupil.common.security.dto.LoginUser;
import cn.unknowpupil.common.security.utils.CaptchaUtil;
import cn.unknowpupil.common.security.utils.SecurityUtils;
import cn.unknowpupil.domain.dto.login.RouterVo;
import cn.unknowpupil.domain.dto.login.UsernamePasswordLoginDto;
import cn.unknowpupil.domain.system.SysMenu;
import cn.unknowpupil.domain.system.SysUser;
import cn.unknowpupil.common.log.manager.AsyncFactory;
import cn.unknowpupil.common.log.manager.AsyncManager;
import cn.unknowpupil.service.system.ISysMenuService;
import cn.unknowpupil.service.system.ISysRoleService;
import cn.unknowpupil.service.system.ISysUserService;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * Created at 2020/10/19 by w10g <br>
 * Initialize LoginController ... <br>
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@Api(tags = {"系统-登录模块"}, value = "LoginController")
@RestController
@RequestMapping(value = "admin")
@RequiredArgsConstructor
public class LoginController {
    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
    private final ISysUserService sysUserService;
    private final CaptchaUtil captchaUtil;
    private final TokenService tokenService;
    private final AuthenticationManagerBuilder authenticationManagerBuilder;
    private final ISysRoleService sysRoleService;
    private final ISysMenuService sysMenuService;
    private final AsyncManager asyncManager;

    /**
     * 登录验证
     *
     * @param dto 唯一标识
     * @return 结果
     */
    @ApiOperation("系统：登录验证")
    @PostMapping("login")
    public ResultResponse login(@RequestBody @Validated UsernamePasswordLoginDto dto) throws Exception {
        // 这个步骤 和直接去校验 目前不清楚意义。
        // 密码解密
        String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, dto.getPassword());
        dto.setPassword(password);
        UsernamePasswordLoginAuthentication authenticationToken = new UsernamePasswordLoginAuthentication(dto, null);
        Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        LoginUser user = (LoginUser) authentication.getPrincipal();
        String token = tokenService.createToken(user);
        asyncManager.execute(AsyncFactory.updateUser(user.getId()));
        logger.info("登录成功-------token: {}", token);
        return ResultResponse.buildSuccess(token);

    }

    @ApiOperation("系统：获取用户详情")

    @GetMapping("info")
    public ResultResponse userInfo() {

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = sysUserService.info(loginUser.getId());
        // 角色集合
        Set<String> roles = sysRoleService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = sysRoleService.getMenuPermission(user);
        Map<String, Object> result = Maps.newHashMap();

        result.put("user", user);
        result.put("roles", roles);
        result.put("permissions", permissions);

        return ResultResponse.buildSuccess(result);
    }


    /**
     * 获取验证码
     */
    @ApiOperation("系统：退出登录")
    @PostMapping(value = "logout", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultResponse logout() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        tokenService.logout(loginUser.getToken());
        asyncManager.execute(AsyncFactory.recordLoginInfo(loginUser.getUsername(), LoginEnum.LOGOUT, "退出成功"));
        return ResultResponse.success("退出成功");
    }

    @ApiOperation("系统：获取验证码")
    @GetMapping(value = "captcha", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResultResponse captcha() {

        return ResultResponse.buildSuccess(captchaUtil.getCaptchaCode());
    }


    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("routers")
    @ApiOperation("系统：路由信息")
    public ResultResponse getRouters() {
        long begin = System.currentTimeMillis();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 用户信息

        List<SysMenu> menus = sysMenuService.selectMenuTreeByUserId(loginUser.getId());
        List<RouterVo> routerVos = sysMenuService.buildMenus(menus);
        System.err.println("获取路由耗时：" + (System.currentTimeMillis() - begin));
        return ResultResponse.buildSuccess(routerVos);
    }
}
